using TestCases.Assertions;
using TestCases.CompareAssert.Core.Formatters;
using TestCases.CompareAssert.Core.Interfaces;
using TestCases.CompareAssert.Settings.Interfaces;

namespace TestCases.CompareAssert.Settings
{
    public class CAssertOptions : IAssertionOptions
    {
        #region Static members. Default values.
        private static IAssertion _defaultAssertion;
        private static IResultBuilderFactory _defaultFactory;
        private static IResultFormatter _defaultFormatter;
        
        static CAssertOptions()
        {
            DefaultTraceRules = TraceRules.Failed;
        }

        public static CAssertOptions DefaultInstance
        {
            get { return DefaultInitializer.Instance; }
        }

        public static TraceRules DefaultTraceRules { get; set; }

        public static IResultBuilderFactory DefaultFactory
        {
            get
            {
                if (_defaultFactory == null)
                {
                    _defaultFactory = BuilderFactory.Simple;
                }
                return _defaultFactory;
            }
            set { _defaultFactory = value; }
        }

        public static IResultFormatter DefaultFormatter
        {
            get
            {
                if (_defaultFormatter == null)
                {
                    _defaultFormatter = ResultFormatter.Instance;
                }
                return _defaultFormatter;
            }
            set { _defaultFormatter = value; }
        }

        public static IAssertion DefaultAssertion
        {
            get
            {
                if (_defaultAssertion == null)
                {
                    _defaultAssertion = AssertionUtils.Instance;
                }
                return _defaultAssertion;
            }
            set { _defaultAssertion = value; }
        }

        private static class DefaultInitializer
        {
// ReSharper disable EmptyConstructor

            internal static readonly CAssertOptions Instance = new CAssertOptions();

            static DefaultInitializer()
// ReSharper restore EmptyConstructor
            {
            }
        }

        #endregion
                
        #region Options members
        private IAssertion _assertion;
        private IResultBuilderFactory _factory;
        private IResultFormatter _formatter;
        private TraceRules? _traceRules;

        public TraceRules TraceRules
        {
            get { return _traceRules ?? DefaultTraceRules; }
            set { _traceRules = value; }
        }

        public IResultBuilderFactory Factory
        {
            get { return _factory ?? DefaultFactory; }
            set { _factory = value; }
        }

        public IResultFormatter Formatter
        {
            get { return _formatter ?? DefaultFormatter; }
            set { _formatter = value; }
        }

        public IAssertion Assertion
        {
            get { return _assertion ?? DefaultAssertion; }
            set { _assertion = value; }
        }
        #endregion
    }
}